﻿#region 命名空间
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Xml.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using Microsoft.Win32;
using Microsoft.WindowsAPICodePack.Dialogs;
using DW.WPFToolkit;
using Xceed.Wpf.Toolkit.PropertyGrid;
using Microsoft.Xna.Framework.Content.Pipeline;
using MonoGameContentProcessors;
using MonoGameContentBuild;
#endregion

namespace ContentFactory
{
    /// <summary>
    /// ContentFactory 主窗体。
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 字段

        Project _project;

        #endregion

        #region 初始化

        /// <summary>
        /// 初始化。
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            // 初始化素材管道。
            ContentBuildSystem.RegisterLogger(new CustomContentBuildLogger());
            PipelineManager.Initialize();
            comboBoxPlatform.ItemsSource = Enum.GetValues(typeof(MonoGamePlatform));
            comboBoxImporter.ItemsSource = PipelineManager.GetImporterAttributes();
            comboBoxProcessor.ItemsSource = PipelineManager.GetProcessorAttributes();
            listBox.ItemsSource = CustomContentBuildLogger.Messages;
            // 初始化语言列表。
            string languagesDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Languages");
            if (Directory.Exists(languagesDirectory))
            {
                DirectoryInfo languagesDirectoryInfo = new DirectoryInfo(languagesDirectory);
                DirectoryInfo[] directories = languagesDirectoryInfo.GetDirectories();
                foreach (var directory in directories)
                {
                    string language = directory.Name;
                    MenuItem menuItem = new MenuItem()
                    {
                        Header = language,
                    };
                    menuItem.Click += this.MenuItem_Language_Click;
                    menuItemLanguages.Items.Add(menuItem);
                }
            }
        }

        #endregion

        #region 方法

        // 设置当前项目。
        void SetProject(Project project)
        {
            _project = project;
            string projectName = string.IsNullOrWhiteSpace(_project.SavePath) ? "未命名" : Path.GetFileNameWithoutExtension(_project.SavePath);
            Title = string.Format("{0} - Content Factory", projectName);
            treeListView.ItemsSource = _project.RootDirectories;
            GridView gridView = treeListView.View as GridView;
            foreach (var gameDirectory in _project.Configurations)
            {
                GridViewColumn column = gridView.Columns[(int)gameDirectory.GamePlatform];
                column.Width = gameDirectory.Build ? 96 : 0.0;
                gameDirectory.PropertyChanged += GameDirectory_PropertyChanged;
            }
            foreach (var directory in _project.RootDirectories)
            {
                this.RegisterHandlers(directory);
            }
            _project.ContentAdded += (content) =>
            {
                content.NameChanged += this.ContentObject_NameChanged;
                content.PropertyChanged += this.Content_PropertyChanged;
            };
            _project.ContentRemoved += (content) =>
            {
                content.NameChanged -= this.ContentObject_NameChanged;
                content.PropertyChanged -= this.Content_PropertyChanged;
            };
            _project.DirectoryAdded += (directory) => { directory.NameChanged += this.ContentObject_NameChanged; };
            _project.DirectoryRemoved += (directory) => { directory.NameChanged -= this.ContentObject_NameChanged; };
        }

        // 注册事件处理器。
        void RegisterHandlers(ContentDirectory directory)
        {
            directory.NameChanged += this.ContentObject_NameChanged;
            foreach (var child in directory.Children)
            {
                if (child is ContentBuilder)
                {
                    ContentBuilder content = child as ContentBuilder;
                    content.NameChanged += this.ContentObject_NameChanged;
                    content.PropertyChanged += this.Content_PropertyChanged;
                }
                else
                    this.RegisterHandlers(child as ContentDirectory);
            }
        }

        // 生成素材的二进制文件。
        void BuildContent(ContentBuilder content, MonoGamePlatform targetPlatform)
        {
            if (targetPlatform == MonoGamePlatform.None) return;
            ContentState state = content.GetState(targetPlatform);
            if (state == ContentState.UnCreated ||
                (checkBoxForced.IsChecked.Value && content.GetState(targetPlatform) == ContentState.Created))
            {
                content.SetState(targetPlatform, ContentState.Creating);
                string output = this.GetContentOutput(targetPlatform, content);
                Thread thread = new Thread(() =>
                {
                    try
                    {
                        content.Build(output, targetPlatform, null);
                        this.Dispatcher.Invoke((Action)(() =>
                        {
                            content.SetState(targetPlatform, ContentState.Created);
                        }));
                    }
                    catch (Exception e)
                    {
                        this.Dispatcher.Invoke((Action)(() =>
                        {
                            CustomContentBuildLogger.Log(e.InnerException.Message);
                            content.SetState(targetPlatform, ContentState.UnCreated);
                        }));
                    }
                });
                thread.Start();
            }
        }

        // 获取素材目录的输出路径。
        string GetDirectoryOutput(MonoGamePlatform targetPlatform, ContentDirectory directory, string directoryName = null)
        {
            List<string> paths = new List<string>();
            paths.Add(directoryName ?? directory.Name);
            ContentDirectory parent = directory.Parent;
            while (parent != null)
            {
                paths.Insert(0, parent.Name);
                parent = parent.Parent;
            }
            paths.Insert(0, this.GetPlatformDirectory(targetPlatform));
            return Path.Combine(paths.ToArray());
        }

        // 获取素材的输出路径。
        string GetContentOutput(MonoGamePlatform targetPlatform, ContentBuilder content, string contentName = null)
        {
            List<string> paths = new List<string>();
            contentName = contentName ?? content.Name;
            paths.Add(contentName + ".xnb");
            ContentDirectory directory = content.Parent;
            while (directory != null)
            {
                paths.Insert(0, directory.Name);
                directory = directory.Parent;
            }
            paths.Insert(0, this.GetPlatformDirectory(targetPlatform));
            return Path.Combine(paths.ToArray());
        }

        // 获取素材的相对输出路径。
        string GetRelativeContentOutput(ContentBuilder content)
        {
            List<string> paths = new List<string>();
            paths.Add(content.Name + ".xnb");
            ContentDirectory directory = content.Parent;
            while (directory != null)
            {
                paths.Insert(0, directory.Name);
                directory = directory.Parent;
            }
            return Path.Combine(paths.ToArray());
        }

        // 获取目录下所有素材。
        void GetContents(List<ContentBuilder> contents, ContentDirectory directory, bool child)
        {
            foreach (var obj in directory.Children)
            {
                if (obj is ContentBuilder)
                    contents.Add(obj as ContentBuilder);
                else if (child)
                    this.GetContents(contents, obj as ContentDirectory, child);
            }
        }

        // 返回当前游戏平台的生成目录。
        string GetPlatformDirectory(MonoGamePlatform targetPlatform)
        {
            Configuration config = _project.GetConfig(targetPlatform);
            return config != null ? config.ProjectDirectory : null;
        }

        // 检查当前游戏平台是否开启。
        bool CheckPlatform()
        {
            MonoGamePlatform platform = (MonoGamePlatform)comboBoxPlatform.SelectedItem;
            Configuration config = _project.GetConfig(platform);
            return config != null && config.Build;
        }

        // 检查当前游戏平台的项目是否设置。
        bool CheckPlatformProject()
        {
            MonoGamePlatform platform = (MonoGamePlatform)comboBoxPlatform.SelectedItem;
            Configuration config = _project.GetConfig(platform);
            return config != null && config.ProjectFile != null;
        }

        // 返回当前游戏平台的项目文件。
        string GetPlatformProject()
        {
            MonoGamePlatform platform = (MonoGamePlatform)comboBoxPlatform.SelectedItem;
            Configuration config = _project.GetConfig(platform);
            return config != null ? config.ProjectFile : null;
        }

        // 更新游戏项目的元素。
        void UpdateElement(XElement parent, XNamespace space, ContentDirectory directory)
        {
            foreach (var child in directory.Children)
            {
                if (child is ContentBuilder)
                {
                    ContentBuilder content = child as ContentBuilder;
                    parent.Add(new XElement(space + "None", new XAttribute("Include", this.GetRelativeContentOutput(content)),
                        new XElement(space + "CopyToOutputDirectory", "PreserveNewest")));
                }
                else
                {
                    this.UpdateElement(parent, space, child as ContentDirectory);
                }
            }
        }

        #endregion

        #region 命令处理

        // 新建 命令是否能执行。
        private void Command_New_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        // 新建 命令执行。
        private void Command_New_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Project project = Project.Create();
            ProjectSettingsDialog dialog = new ProjectSettingsDialog()
            {
                Project = project,
                Owner = this,
            };
            dialog.ShowDialog();
            project.RootDirectories.Add(new ContentDirectory()
            {
                Project = project,
                Name = "Content",
            });
            this.SetProject(project);
        }

        // 打开 命令是否能执行。
        private void Command_Open_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        // 打开 命令执行。
        private void Command_Open_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog()
            {
                Title = "选择要打开的项目文件：",
                Filter = "MonoGame Content Project|*.mcp",
                Multiselect = false,
            };
            if (dialog.ShowDialog(this) == true)
            {
                Project project = Project.Load(dialog.FileName);
                project.SavePath = dialog.FileName;
                this.SetProject(project);
            }
        }

        // 保存 命令是否能执行。
        private void Command_Save_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && _project.Dirty;
        }

        // 保存 命令执行。
        private void Command_Save_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (File.Exists(_project.SavePath))
            {
                _project.Save(_project.SavePath);
            }
            else
            {
                this.Command_SaveAs_Executed(sender, e);
            }
        }

        // 另存为 命令是否能执行。
        private void Command_SaveAs_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null;
        }

        // 另存为 命令执行。
        private void Command_SaveAs_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SaveFileDialog dialog = new SaveFileDialog()
            {
                Title = "选择要保存项目的路径：",
                DefaultExt = ".mcp",
                Filter = "MonoGame Content Project|*.mcp",
            };
            if (dialog.ShowDialog(this) == true)
            {
                _project.Save(dialog.FileName);
                _project.SavePath = dialog.FileName;
            }
        }

        // 设置 命令是否能执行。
        private void Command_Settings_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null;
        }

        // 设置 命令执行。
        private void Command_Settings_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ProjectSettingsDialog dialog = new ProjectSettingsDialog()
            {
                Project = _project,
                Owner = this,
            };
            dialog.ShowDialog();
        }

        // 退出 命令是否能执行。
        private void Command_Close_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        // 退出 命令执行。
        private void Command_Close_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

        // 删除 命令是否能执行。
        private void Command_Delete_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && treeListView != null && treeListView.SelectedItem is ViewObject;
        }

        // 删除 命令执行。
        private void Command_Delete_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (treeListView.SelectedItem is ContentBuilder)
            {
                ContentBuilder content = treeListView.SelectedItem as ContentBuilder;
                content.Parent.RemoveContent(content);
            }
            else
            {
                ContentDirectory directory = treeListView.SelectedItem as ContentDirectory;
                directory.Parent.RemoveDirectory(directory);
            }
            _project.Dirty = true;
        }

        // 替换 命令是否能执行。
        private void Command_Replace_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && treeListView != null && treeListView.SelectedItem is ContentBuilder;
        }

        // 替换 命令执行。
        private void Command_Replace_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ContentBuilder content = treeListView.SelectedItem as ContentBuilder;
            OpenFileDialog dialog = new OpenFileDialog()
            {
                Title = "选择要导入的本地文件：",
                Multiselect = false,
            };
            if (dialog.ShowDialog(this) == true)
            {
                ContentImporterAttribute importerAttribute = PipelineManager.GetDefaultImporterAttribute(dialog.FileName);
                if (importerAttribute == null)
                {
                    CustomContentBuildLogger.Log(string.Format("替换“{0}”出错！找不到该类素材的导入器。", dialog.FileName));
                    return;
                }
                content.FileName = dialog.FileName;
                content.ImporterAttribute = importerAttribute;
                content.ProcessorAttribute = PipelineManager.GetDefaultProcessorAttribute(importerAttribute);
                _project.Dirty = true;
            }
        }

        // 生成 命令是否能执行。
        private void Command_Build_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && this.CheckPlatform() &&
                treeListView != null && treeListView.SelectedItem is ViewObject;
        }

        // 生成 命令执行。
        private void Command_Build_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MonoGamePlatform targetPlatform = (MonoGamePlatform)comboBoxPlatform.SelectedItem;
            if (treeListView.SelectedItem is ContentBuilder)
            {
                ContentBuilder content = treeListView.SelectedItem as ContentBuilder;
                this.BuildContent(content, targetPlatform);
            }
            else
            {
                ContentDirectory directory = treeListView.SelectedItem as ContentDirectory;
                List<ContentBuilder> contents = new List<ContentBuilder>();
                this.GetContents(contents, directory, checkBoxChild.IsChecked.Value);
                foreach (var content in contents)
                {
                    this.BuildContent(content, targetPlatform);
                }
            }
            _project.Dirty = true;
        }

        // 生成全部 命令是否能执行。
        private void Command_BuildAll_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && this.CheckPlatform();
        }

        // 生成全部 命令执行。
        private void Command_BuildAll_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MonoGamePlatform targetPlatform = (MonoGamePlatform)comboBoxPlatform.SelectedItem;
            List<ContentBuilder> contents = new List<ContentBuilder>();
            foreach (var root in _project.RootDirectories)
            {
                this.GetContents(contents, root, true);
            }
            foreach (var content in contents)
            {
                this.BuildContent(content, targetPlatform);
            }
            _project.Dirty = true;
        }

        // 更新项目 命令是否能执行。
        private void Command_Update_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && this.CheckPlatformProject();
        }

        // 更新项目 命令执行。
        private void Command_Update_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            const string ContentCondition = "'ContentFactory'!=''";
            string projectFile = this.GetPlatformProject();
            if (File.Exists(projectFile) && Path.GetExtension(projectFile).ToUpper() == ".CSPROJ")
            {
                XDocument doc = XDocument.Load(projectFile);
                XNamespace space = doc.Root.Name.Namespace;
                IEnumerable<XElement> itemGroups = doc.Root.Descendants(space + "ItemGroup");
                XElement contentItemGroup = null;
                foreach (var itemGroup in itemGroups)
                {
                    XAttribute attribute = itemGroup.Attribute("Condition");
                    if (attribute != null && attribute.Value == ContentCondition)
                    {
                        contentItemGroup = itemGroup;
                        break;
                    }
                }
                if (contentItemGroup == null)
                {
                    contentItemGroup = new XElement(space + "ItemGroup", new XAttribute("Condition", ContentCondition));
                    doc.Root.Add(contentItemGroup);
                }
                else
                    contentItemGroup.RemoveNodes();
                foreach (var root in _project.RootDirectories)
                {
                    this.UpdateElement(contentItemGroup, space, root);
                }
                doc.Save(projectFile);
            }
        }

        // 导入 命令是否能执行。
        private void Command_Import_CanExecute(object sender, System.Windows.Input.CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && treeListView != null && treeListView.SelectedItem is ViewObject;
        }

        // 导入 命令执行。
        private void Command_Import_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog()
            {
                Title = "选择要导入的本地文件：",
                Multiselect = true,
            };
            if (dialog.ShowDialog(this) == true)
            {
                ContentDirectory parent = treeListView.SelectedItem is ContentDirectory
                    ? (treeListView.SelectedItem as ContentDirectory)
                    : (treeListView.SelectedItem as ContentBuilder).Parent;
                foreach (var fileName in dialog.FileNames)
                {
                    if (!File.Exists(fileName))
                        continue;
                    ContentImporterAttribute importerAttribute = PipelineManager.GetDefaultImporterAttribute(fileName);
                    if (importerAttribute == null)
                    {
                        CustomContentBuildLogger.Log(string.Format("导入“{0}”出错！找不到该类素材的导入器。", fileName));
                        continue;
                    }
                    parent.AddContent(new ContentBuilder()
                    {
                        FileName = fileName,
                        Name = Path.GetFileNameWithoutExtension(fileName),
                        CompressContent = _project.DefaultCompressContent,
                        ImporterAttribute = importerAttribute,
                        ProcessorAttribute = PipelineManager.GetDefaultProcessorAttribute(importerAttribute),
                    });
                }
                if (treeListView.SelectedItem is ContentDirectory)
                {
                    TreeListViewItem treeListViewItem = treeListView.ItemContainerGenerator.ContainerFromItem(treeListView.SelectedItem) as TreeListViewItem;
                    if (treeListViewItem != null)
                        treeListViewItem.IsExpanded = true;
                }
                _project.Dirty = true;
            }
        }

        // 创建 命令是否能执行。
        private void Command_Create_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && treeListView != null && treeListView.SelectedItem is ViewObject;
        }

        // 创建 命令执行。
        private void Command_Create_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CreateCustomDataDialog createDialog = new CreateCustomDataDialog()
            {
                Owner = this,
            };
            if (createDialog.ShowDialog() == true)
            {
                CommonSaveFileDialog fileDialog = new CommonSaveFileDialog()
                {
                    Title = "选择自定义数据的保存路径：",
                    DefaultExtension = ".xml",
                };
                fileDialog.Filters.Add(new CommonFileDialogFilter("Xml 文档", "*.xml"));
                if (fileDialog.ShowDialog(this) == CommonFileDialogResult.Ok)
                {
                    try
                    {
                        object customData = Activator.CreateInstance(createDialog.DataType);
                        CustomDataEditDialog editDialog = new CustomDataEditDialog()
                        {
                            Owner = this,
                            CustomData = customData,
                            SavePath = fileDialog.FileName,
                        };
                        editDialog.Save();
                        ContentDirectory parent = treeListView.SelectedItem is ContentDirectory
                            ? (treeListView.SelectedItem as ContentDirectory)
                            : (treeListView.SelectedItem as ContentBuilder).Parent;
                        ContentImporterAttribute importerAttribute = PipelineManager.GetDefaultImporterAttribute(fileDialog.FileName);
                        parent.AddContent(new ContentBuilder()
                        {
                            FileName = fileDialog.FileName,
                            Name = Path.GetFileNameWithoutExtension(fileDialog.FileName),
                            CompressContent = _project.DefaultCompressContent,
                            ImporterAttribute = importerAttribute,
                            ProcessorAttribute = PipelineManager.GetDefaultProcessorAttribute(importerAttribute),
                        });
                        if (treeListView.SelectedItem is ContentDirectory)
                        {
                            TreeListViewItem treeListViewItem = treeListView.ItemContainerGenerator.ContainerFromItem(treeListView.SelectedItem) as TreeListViewItem;
                            if (treeListViewItem != null)
                                treeListViewItem.IsExpanded = true;
                        }
                        editDialog.Show();
                        _project.Dirty = true;
                    }
                    catch (Exception exception)
                    {
                    }
                }
            }
        }

        // 编辑 命令是否能执行。
        private void Command_Edit_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && treeListView != null && treeListView.SelectedItem is ContentBuilder;
        }

        // 编辑 命令执行。
        private void Command_Edit_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ContentBuilder content = treeListView.SelectedItem as ContentBuilder;
            if (Path.GetExtension(content.FileName).ToUpper() == ".XML")
            {
                CustomDataEditDialog editDialog = new CustomDataEditDialog()
                {
                    Owner = this,
                    SavePath = content.FileName,
                };
                editDialog.Load();
                editDialog.Show();
            }
            else
            {
                Process process = new Process();
                process.StartInfo.FileName = content.FileName;
                process.Start(); 
            }
        }

        // 添加根目录 命令是否能执行。
        private void Command_AddRoot_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null;
        }

        // 添加根目录 命令执行。
        private void Command_AddRoot_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            _project.RootDirectories.Add(new ContentDirectory()
            {
                Name = "Root",
                Project = _project,
            });
            _project.Dirty = true;
        }

        // 添加目录 命令是否能执行。
        private void Command_AddDir_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _project != null && treeListView != null && treeListView.SelectedItem is ViewObject;
        }

        // 添加目录 命令执行。
        private void Command_AddDir_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ContentDirectory parent = treeListView.SelectedItem is ContentDirectory
                ? (treeListView.SelectedItem as ContentDirectory)
                : (treeListView.SelectedItem as ContentBuilder).Parent;
            parent.AddDirectory(new ContentDirectory()
            {
                Name = "Directory",
                Project = _project,
            });
            if (treeListView.SelectedItem is ContentDirectory)
            {
                TreeListViewItem treeListViewItem = treeListView.ItemContainerGenerator.ContainerFromItem(treeListView.SelectedItem) as TreeListViewItem;
                if (treeListViewItem != null)
                    treeListViewItem.IsExpanded = true;
            }
            _project.Dirty = true;
        }

        #endregion

        #region 事件处理

        // 项目的游戏目录设置更改后调用。
        void GameDirectory_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            Configuration gameDirectory = sender as Configuration;
            GridView gridView = treeListView.View as GridView;
            GridViewColumn column = gridView.Columns[(int)gameDirectory.GamePlatform];
            column.Width = gameDirectory.Build ? 96 : 0.0;
            _project.Dirty = true;
        }

        // 素材（目录）名称更改后调用。
        void ContentObject_NameChanged(ContentObject obj, string oldName, string newName)
        {
            if (obj is ContentBuilder)
            {
                ContentBuilder content = obj as ContentBuilder;
                foreach (var gameDirectory in _project.Configurations)
                {
                    if (gameDirectory.Build)
                    {
                        string oldContent = this.GetContentOutput(gameDirectory.GamePlatform, content, oldName);
                        if (File.Exists(oldContent))
                        {
                            string newContent = this.GetContentOutput(gameDirectory.GamePlatform, content, newName);
                            File.Move(oldContent, newContent);
                        }
                    }
                }
            }
            else
            {
                ContentDirectory directory = obj as ContentDirectory;
                foreach (var gameDirectory in _project.Configurations)
                {
                    if (gameDirectory.Build)
                    {
                        string oldDir = this.GetDirectoryOutput(gameDirectory.GamePlatform, directory, oldName);
                        if (Directory.Exists(oldDir))
                        {
                            string newDir = this.GetDirectoryOutput(gameDirectory.GamePlatform, directory, newName);
                            Directory.Move(oldDir, newDir);
                        }
                    }
                }
            }
            _project.Dirty = true;
        }

        // 素材属性更改后调用。
        void Content_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            ContentBuilder content = sender as ContentBuilder;
            if (e.PropertyName == "FileName" || e.PropertyName == "CompressContent" ||
                e.PropertyName == "Importer" || e.PropertyName == "Processor")
            {
                content.ClearState();
            }
            _project.Dirty = true;
        }

        #region WPF 事件

        // 窗体鼠标按下后。
        private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (textBoxName.IsFocused == true)
                treeListView.Focus();
        }

        // 窗体关闭时。
        private void Window_Closing(object sender, CancelEventArgs e)
        {
            if (_project != null && _project.Dirty)
            {
                MessageBoxResult result = MessageBox.Show("素材项目已编辑，是否现在保存？", "Content Factory", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
                if (result == MessageBoxResult.Yes)
                {
                    this.Command_Save_Executed(null, null);
                }
                else if (result == MessageBoxResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }

        // 属性网格控件属性更改后。
        private void PropertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
        {
            PropertyGrid propertyGrid = sender as PropertyGrid;
            ContentBuilder content = treeListView.SelectedItem as ContentBuilder;
            if (content != null)
            {
                if (content.Importer == propertyGrid.SelectedObject ||
                    content.Processor == propertyGrid.SelectedObject)
                {
                    content.ClearState();
                }
            }
        }

        // 树形视图控件双击项后。
        private void TreeListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (treeListView.SelectedItem is ContentBuilder)
            {
                this.Command_Edit_Executed(null, null);
            }
        }

        // 语言 菜单项点击后。
        void MenuItem_Language_Click(object sender, RoutedEventArgs e)
        {
            MenuItem menuItem = sender as MenuItem;
            string language = (string)menuItem.Header;
            (Application.Current as App).ApplyLanguage(language);
        }

        // 关于 菜单项点击后。
        private void MenuItem_About_Click(object sender, RoutedEventArgs e)
        {
            (new AboutDialog()).ShowDialog();
        }

        #endregion

        #endregion
    }
}
